package com.lt.integration.jpa.validation;

import cn.hutool.core.bean.BeanUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;

import static org.springframework.util.StringUtils.isEmpty;

/**
 * @author: xiaobin
 * @create: 2020-05-12 15:23
 */
public class ConditionalValidator implements ConstraintValidator<Conditional, Object> {

    private static final Logger log = LoggerFactory.getLogger(ConditionalValidator.class);

    private String selected;
    private String[] required;
    private String message;
    private String[] values;

    @Override
    public void initialize(Conditional requiredIfChecked) {
        selected = requiredIfChecked.selected();
        required = requiredIfChecked.required();
        message = requiredIfChecked.message();
        values = requiredIfChecked.values();
    }

    @Override
    public boolean isValid(Object object, ConstraintValidatorContext context) {
        Boolean valid = true;

        // 如果values为空 则检查selected不为空，就去检查required中的值
        if (null == values || values.length == 0) {
            Object checkedValue = BeanUtil.getFieldValue(object, selected);
            if (!isEmpty(checkedValue)) {
                for (String propName : required) {
                    Object requiredValue = BeanUtil.getFieldValue(object, propName);
                    valid = requiredValue != null && !isEmpty(requiredValue);
                    log.debug("value: {}", requiredValue);
                    if (!valid) {
                        context.disableDefaultConstraintViolation();
                        context.buildConstraintViolationWithTemplate(message).addPropertyNode(propName).addConstraintViolation();
                    }
                }
            }
        } else {
            Object checkedValue = BeanUtil.getFieldValue(object, selected);
            if (null != checkedValue) {
                String checkedValueStr = checkedValue.toString();
                if (Arrays.asList(values).contains(checkedValueStr)) {
                    for (String propName : required) {
                        Object requiredValue = BeanUtil.getFieldValue(object, propName);
                        valid = requiredValue != null && !isEmpty(requiredValue);
                        log.debug("value: {}", requiredValue);
                        if (!valid) {
                            context.disableDefaultConstraintViolation();
                            context.buildConstraintViolationWithTemplate(message).addPropertyNode(propName).addConstraintViolation();
                        }
                    }
                }
            } else {
                valid = false;
                context.disableDefaultConstraintViolation();
                context.buildConstraintViolationWithTemplate(message).addPropertyNode(selected).addConstraintViolation();
            }
        }

        return valid;
    }
}
